package
{
	import air.update.ApplicationUpdaterUI;
	import air.update.events.StatusUpdateEvent;
	import air.update.events.UpdateEvent;

	import flash.desktop.NativeApplication;
	import flash.desktop.Updater;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.filesystem.File;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	import flash.utils.setTimeout;

	import mx.controls.Alert;
	import mx.events.CloseEvent;

	import spark.components.WindowedApplication;

	import utils.FilesUtil;

	/**
	 *
	 * Air更新管理器。支持桌面和本机扩展的自动更新。
	 *
	 *
	 * 配合此update.xml使用
	 * <?xml version="1.0" encoding="UTF-8"?>
		<update xmlns="http://ns.adobe.com/air/framework/update/description/2.5">
			<versionNumber>0.0.1</versionNumber>
			<url>http://XXX/XXX.air</url>
			<description>
				<text xml:lang="zh_CN"><![CDATA[
					更新说明
				]]></text>
			</description>
		</update>
	 *
	 */
	public class UpdateManager
	{
		static private var appUpdater:ApplicationUpdaterUI=new ApplicationUpdaterUI();
		static private var app:WindowedApplication;


		/**
		 * 检查并更新
		 * @param updateURL  配置文件update.xml的URL地址。
		 * @param app	     主应用的app WindowedApplication
		 * @return
		 *
		 */
		static public function checkForUpdate(updateURL:String, app:WindowedApplication):ApplicationUpdaterUI
		{
			UpdateManager.app=app;
			NativeApplication.nativeApplication.addEventListener(Event.EXITING, function(e:Event):void
			{
				var opened:Array=NativeApplication.nativeApplication.openedWindows;
				for (var i:int=0; i < opened.length; i++)
				{
					opened[i].close();
				}
			});
			trace("检查更新：", updateURL);
			appUpdater.updateURL=updateURL + "?" + Math.random();
			appUpdater.isCheckForUpdateVisible=false;
			appUpdater.isDownloadProgressVisible=false;
			appUpdater.isDownloadUpdateVisible=false;
			appUpdater.addEventListener(UpdateEvent.INITIALIZED, onUpdate);
			appUpdater.addEventListener(ErrorEvent.ERROR, onError);
			appUpdater.addEventListener(StatusUpdateEvent.UPDATE_STATUS, UPDATE_STATUS);
			appUpdater.initialize();
			return appUpdater;
		}

		protected static function UPDATE_STATUS(event:StatusUpdateEvent):void
		{
			//trace("最新版本：", event.version, event.available, appUpdater.currentVersion);
			//如果可以更新，但系统不支持内置更新，那只能手动更新
			//这个是针对本机扩展的更新，发布成exe的那种。
			if (Updater.isSupported == false && event.available)
			{
				Alert.show("发现有新版本可更新，是否立即更新？\n当前版本：" + appUpdater.currentVersion + "\n最新版本：" + event.version, "版本可更新", Alert.OK | Alert.CANCEL, null, function(e:CloseEvent):void
				{
					if (e.detail == Alert.OK)
					{
						updateDownload();
					}
				});
			}
		}

		static private function updateDownload():void
		{
			var xml:XMLList=appUpdater.updateDescriptor.children();
			if (xml)
			{
				var appURL:String=xml.(localName() == "url");
				if (appURL && appURL != "")
				{
					//下载更新应用
					UpdateManager.app.status="正在准备更新，请稍候....";
					var stream:URLStream=new URLStream();
					stream.addEventListener(Event.COMPLETE, function(e:Event):void
					{
						var fileData:ByteArray=new ByteArray();
						stream.readBytes(fileData, 0, stream.bytesAvailable);
						stream.close();
						//写入临时文件
						var fileName:String=appURL.substr(appURL.lastIndexOf("/") + 1, appURL.length);
						var saveFile:File=File.applicationStorageDirectory.resolvePath(fileName);
						if (saveFile.exists)
						{
							try
							{
								saveFile.deleteFile();
							}
							catch (error:Error)
							{
							}
						}
						trace("更新文件临时保存位置：", saveFile.nativePath);
						FilesUtil.saveBytes(saveFile, fileData);
						try
						{
							//开打应用
							saveFile.openWithDefaultApplication();
							//退出本机应用
							setTimeout(NativeApplication.nativeApplication.exit, 1000);
						}
						catch (error:Error)
						{
							Alert.show("运行更新内容时出现问题。\n" + error.message, "更新失败");
							return;
						}
					});
					stream.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void
					{
						UpdateManager.app.status="正在更新，请稍候...." + int(e.bytesLoaded / e.bytesTotal * 100) + "%";
					});
					stream.load(new URLRequest(appURL + "?" + Math.random()));
				}
			}
		}

		static private function onError(event:ErrorEvent):void
		{
			Alert.show(event.toString());
		}

		static private function onUpdate(event:UpdateEvent):void
		{
			appUpdater.checkNow();
		}
	}
}
